package com.acc.store.service.impl;

import com.acc.store.entity.Orders;
import com.acc.store.entity.ShopCar;
import com.acc.store.entity.User;
import com.acc.store.mapper.OrderMapper;
import com.acc.store.service.OrderService;
import com.acc.store.service.ShopCarService;
import com.acc.store.vo.CountVo;
import com.acc.store.vo.OrderVo;
import com.acc.store.vo.UserOrderVo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;


@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Orders>
        implements OrderService {
    @Autowired
    ShopCarService shopCarService;

    @Override
    public IPage getPage(Map<String, Object> params) {
        Long page = Long.valueOf((String) params.get("page"));
        Long limit = Long.valueOf((String) params.get("limit"));
        String key = (String) params.get("name");
        //封装查询语句
        IPage<Orders> orderPage = baseMapper.selectPage(new Page<>(page, limit), null);
        List<OrderVo> orderVos = orderPage.getRecords().stream().map(item -> {
            OrderVo orderVo = total(item.getId());
            if (orderVo.getTotalPrice().compareTo(BigDecimal.ZERO) <= 0) {
                Db.removeById(orderVo.getId(), Orders.class);
                return null;
            }
            return orderVo;
        }).toList();
        IPage<OrderVo> voPage = new Page<>();
        voPage.setPages(orderPage.getPages());
        voPage.setRecords(orderVos);
        voPage.setTotal(orderPage.getTotal());
        voPage.setCurrent(orderPage.getCurrent());
        return voPage;
    }

    @Override
    public Long create(Long userId) {
        Orders orders = new Orders();
        orders.setStatus(0);
        orders.setUserId(userId);
        orders.setTotalPrice(BigDecimal.valueOf(0));
        save(orders);
        return orders.getId();
    }

    @Override
    public OrderVo total(Long orderid) {
        Orders byId = getById(orderid);
        List<ShopCar> shopCarList = shopCarService.getList(orderid);
        BigDecimal money = BigDecimal.valueOf(0);
        for (ShopCar shopCar : shopCarList) {
            BigDecimal itemTotal = shopCar.getPrice().multiply(BigDecimal.valueOf(shopCar.getNum()));
            money = money.add(itemTotal);
        }
        byId.setTotalPrice(money);
        OrderVo orderVo = new OrderVo();
        BeanUtils.copyProperties(byId, orderVo);
        orderVo.setShopCarList(shopCarList);
        User user = Db.getById(byId.getUserId(), User.class);
        orderVo.setUserName(user.getName());
        return orderVo;
    }

    @Override
    @Transactional
    public void clear() {
        List<Orders> list = lambdaQuery().eq(Orders::getStatus, 0).list();
        List<Long> orderIds = list.stream().map(item -> {
            return item.getId();
        }).toList();
        shopCarService.removeByOrderIds(orderIds);
        removeBatchByIds(orderIds);
    }

    @Override
    public void submit(Long orderId) {
        //订单总价
        OrderVo orderVo = total(orderId);
        Orders byId = getById(orderId);
        byId.setTotalPrice(orderVo.getTotalPrice());
        byId.setStatus(1);
        updateById(byId);
    }

    @Override
    public List<CountVo> counts() {
        List<Orders> ordersThisWeek = timeByOrder(true);
        List<Orders> ordersToday = timeByOrder(false);
        List<CountVo> countVos = new ArrayList<>();
        //今日销售额
        BigDecimal todayPrice = new BigDecimal(0);
        for (Orders orders : ordersToday) {
            todayPrice = todayPrice.add(orders.getTotalPrice());
        }
        counter(countVos, "今日销售额(元)", "success", "#2ec7c9", todayPrice);
        //今日出单
        counter(countVos, "今日顾客人次", "star-on", "#ffb980", ordersToday.size());
        //本周热门商品
        List<Long> weekId = new ArrayList<>();
        ordersThisWeek.forEach(item -> {
            weekId.add(item.getId());
        });
        if (weekId.size() > 0) {
            List<ShopCar> carList = Db.lambdaQuery(ShopCar.class).in(ShopCar::getOrderId, weekId).list();
            Map<String, Integer> map = new HashMap<>();
            String maxName = null;
            int maxCount = 0;
            for (ShopCar car : carList) {
                String name = car.getProductName();
                int count = map.getOrDefault(name, 0) + 1;
                map.put(name, count);
                if (count > maxCount) { // 更新出现次数最多的车型名称和对应的出现次数
                    maxCount = count;
                    maxName = name;
                }
            }
            counter(countVos, "本周热门商品", "s-goods", "#5ab1ef", maxName);
        } else {
            counter(countVos, "本周热门商品", "s-goods", "#5ab1ef", "无数据");
        }
        //本周销售额
        BigDecimal weekPrice = new BigDecimal(0);
        for (Orders orders : ordersThisWeek) {
            weekPrice = weekPrice.add(orders.getTotalPrice());
        }
        counter(countVos, "本周销售额(元)", "success", "#2ec7c9", weekPrice);
        //本周出单
        counter(countVos, "本周顾客人次", "star-on", "#ffb980", ordersThisWeek.size());
        //本周销冠
        Map<Long, Integer> UserMap = new HashMap<>();
        Long maxUserId = null;
        int maxCountt = 0;
        for (Orders orders : ordersThisWeek) {
            Long userId = orders.getUserId();
            int count = UserMap.getOrDefault(userId, 0) + 1;
            UserMap.put(userId, count);
            if (count > maxCountt) { // 更新出现次数最多的用户ID和对应的出现次数
                maxCountt = count;
                maxUserId = userId;
            }
        }
        User byId = Db.getById(maxUserId, User.class);
        if (byId != null) {
            counter(countVos, "本周最佳员工", "s-goods", "#5ab1ef", byId.getName());
        } else {
            counter(countVos, "本周最佳员工", "s-goods", "#5ab1ef", "无数据");

        }
        return countVos;
    }

    @Override
    public List<UserOrderVo> getData() {
        List<Orders> ordersThisWeek = timeByOrder(true);
        List<Orders> ordersToday = timeByOrder(false);
        List<UserOrderVo> voList = new ArrayList<>();
        List<User> userList = Db.lambdaQuery(User.class).eq(User::getStatus, 1).list();
        for (User user : userList) {
            BigDecimal weekSale = new BigDecimal(0);
            for (Orders orders : ordersThisWeek) {
                if (orders.getUserId().equals(user.getId())) {
                    weekSale = weekSale.add(orders.getTotalPrice());
                }
            }
            BigDecimal todaySale = new BigDecimal(0);
            for (Orders orders : ordersToday) {
                if (orders.getUserId().equals(user.getId())) {
                    todaySale = todaySale.add(orders.getTotalPrice());
                }
            }
            UserOrderVo userOrderVo = new UserOrderVo();
            userOrderVo.setUserId(user.getId());
            userOrderVo.setName(user.getName());
            userOrderVo.setTodaySale(todaySale);
            userOrderVo.setWeekSale(weekSale);
            voList.add(userOrderVo);
        }
        return voList;
    }

    @Override
    public List<Map<String, BigDecimal>> getLine() {
        return  baseMapper.getLine();

    }

    private List<Orders> timeByOrder(Boolean falg) {
        List<Orders> list = lambdaQuery().eq(Orders::getStatus, 1).list();
        Date startOfWeek = getStartOfWeek();
        Date startOfDay = getStartOfDay();
        List<Orders> ordersThisWeek = new ArrayList<>();
        List<Orders> ordersToday = new ArrayList<>();
        for (Orders order : list) {
            Date orderDate = order.getCreateTime();
            if (orderDate.after(startOfWeek)) { // 判断订单日期是否在本周开始时间之后
                ordersThisWeek.add(order);
            }
            if (orderDate.after(startOfDay)) { // 判断订单日期是否在本日开始时间之后
                ordersToday.add(order);
            }
        }
        if (falg) {
            return ordersThisWeek;
        } else {
            return ordersToday;
        }
    }

    private void counter(List<CountVo> list, String name, String icon, String color, Object value) {
        CountVo countVo1 = new CountVo();
        countVo1.setName(name);
        countVo1.setIcon(icon);
        countVo1.setColor(color);
        countVo1.setValue(value);
        list.add(countVo1);
    }

    private Date getStartOfWeek() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    private Date getStartOfDay() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }
}




